<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>泛型(generic) | Is2</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="泛型(generic)">
<meta property="og:type" content="article">
<meta property="og:title" content="泛型(generic)">
<meta property="og:url" content="/2015/05/22/c#-generic/index.html">
<meta property="og:site_name" content="Is2">
<meta property="og:description" content="泛型(generic)">
<meta property="og:image" content="/image/cSharp/cSharp65.png">
<meta property="og:image" content="/image/cSharp/cSharp66.png">
<meta property="og:image" content="/image/cSharp/cSharp67.png">
<meta property="og:image" content="/image/cSharp/cSharp68.png">
<meta property="og:image" content="/image/cSharp/cSharp69.png">
<meta property="og:image" content="/image/cSharp/cSharp70.png">
<meta property="og:image" content="/image/cSharp/cSharp71.png">
<meta property="og:image" content="/image/cSharp/cSharp72.png">
<meta property="og:image" content="/image/cSharp/cSharp73.png">
<meta property="og:image" content="/image/cSharp/cSharp74.png">
<meta property="og:image" content="/image/cSharp/cSharp78.png">
<meta property="og:image" content="/image/cSharp/cSharp79.png">
<meta property="og:image" content="/image/cSharp/cSharp80.png">
<meta property="og:image" content="/image/cSharp/cSharp81.png">
<meta property="og:image" content="/image/cSharp/cSharp82.png">
<meta property="og:image" content="/image/cSharp/cSharp83.png">
<meta property="og:image" content="/image/cSharp/cSharp84.png">
<meta property="og:updated_time" content="2016-10-08T12:46:00.937Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="泛型(generic)">
<meta name="twitter:description" content="泛型(generic)">
  
    <link rel="alternate" href="/atom.xml" title="Is2" type="application/atom+xml">
  
  
    <link rel="icon" href="img/logo.ico">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">

  

  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" integrity="sha384-XdYbMnZ/QjLh6iI4ogqCTaIjrFk87ip+ekIjefZch0Y+PvJ8CDYtEs1ipDmPorQ+" crossorigin="anonymous">

  <link rel="stylesheet" href="/css/styles.css" type="text/css">
  

  
  <!--百度统计代码-->
  <script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "//hm.baidu.com/hm.js?37b51d72e2b91d854971620de6fef9bc";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script>
<!--百度自动推送代码-->
<script>
(function(){
    var bp = document.createElement('script');
    bp.src = '//push.zhanzhang.baidu.com/push.js';
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(bp, s);
})();
</script>
<script async src="https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js">
</script>
</head>

<body>
  <nav class="navbar navbar-inverse">
  <div class="container">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#main-menu-navbar" aria-expanded="false">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="main-menu-navbar">
      <ul class="nav navbar-nav">
        
          <li><a class=""
                 href="/index.html">首页</a></li>
        
          <li><a class=""
                 href="/categories/文集/">文集</a></li>
        
          <li><a class=""
                 href="/archives/">归档</a></li>
        
          <li><a class=""
                 href="/resource/">资源</a></li>
        
          <li><a class=""
                 href="/about/">关于</a></li>
        
        <li> <a href="/atom.xml">RSS</a> </li> 
      </ul>

      <!--
      <ul class="nav navbar-nav navbar-right">
        
          <li><a href="/atom.xml" title="RSS Feed"><i class="fa fa-rss"></i></a></li>
        
      </ul>
      -->
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>

  <div class="container">
    <div class="blog-header">
  <h1 class="blog-title">Is2</h1>
  
    <p class="lead blog-description">我只想做的更好</p>
  
</div>

    <div class="row">
        <div class="col-sm-8 blog-main">
          <article id="post-c#-generic" class="article article-type-post" itemscope itemprop="blogPost">

  <header class="article-header">
    
  
    <h1 class="article-title" itemprop="name">
      泛型(generic)
    </h1>
  


  </header>

  <div class="article-meta">
    <div class="article-datetime">
  <a href="/2015/05/22/c#-generic/" class="article-date"><time datetime="2015-05-22T08:17:54.000Z" itemprop="datePublished">2015-05-22</time></a>
</div>

    
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/c/">c#</a>
  </div>

  </div>
  <div class="article-inner">

    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="什么是泛型">什么是泛型</h2><p>　　我们平常所用到的类型都是特定的类型——由编程语言或者BCL(基类库)、程序员自己定义的。为了让代码更加的灵活、解耦，我们可以将类的行为提取出来，使这些相似性的特征不仅可以用在当前的数据类型上，而且还可以扩展到其他的类型上，这样使类更加的有用。<br>　　泛型就是专门处理这种情况的，泛型就可以替代这种抽象的数据类型，泛型就相当于是类型的占位符。<a id="more"></a></p>
<h3 id="示例：">示例：</h3><p>　　假设我们声明了一个<code>MyIntStack</code>类，该类实现了一个int类型的栈，它允许我们把int类型的数据压栈和出栈。<br><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> MyIntStack</span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">int</span> StackPointer=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span>[] StackArray;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">Push</span><span class="params">(<span class="keyword">int</span> x)</span></span><br><span class="line">    </span>&#123;</span><br><span class="line">        <span class="comment">//压栈  </span></span><br><span class="line">    &#125;   </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">pop</span><span class="params">()</span></span><br><span class="line">    </span>&#123;</span><br><span class="line">        <span class="comment">//出栈</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>　　假设我们需要一个float类型的值也具有相同的功能(压栈和出栈),我们需要重新编写针对float类型的代码：<br><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> MyIntStack</span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">int</span> StackPointer=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">float</span>[] StackArray;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">Push</span><span class="params">(<span class="keyword">float</span> x)</span></span><br><span class="line">    </span>&#123;</span><br><span class="line">        <span class="comment">//压栈  </span></span><br><span class="line">    &#125;   </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">float</span> <span class="title">pop</span><span class="params">()</span></span><br><span class="line">    </span>&#123;</span><br><span class="line">        <span class="comment">//出栈</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>　　※ 如果我们需要其他类型的数据也具有压栈和出栈的功能，就前面的做法，需要针对每种类型编写相似的代码，这些亢余代码不仅占据了额外的空间，而且不利于调试和维护。</p>
<h2 id="c#中的泛型">c#中的泛型</h2><p>　　在c#2.0中，微软引入了泛型特性。泛型允许我们声明类型参数化的代码，我们可以使用“<strong>类型占位符</strong>”写代码，然后在创建类的实例的时候提供真实的类型。<br><img src="/image/cSharp/cSharp65.png" alt=""><br>　　★ c#提供了5种泛型：类、结构、接口、委托、方法。其中前四个是类型，而方法是成员。</p>
<h3 id="栈的示例">栈的示例</h3><p>　　我们接着前面的代码，使用泛型处理代码亢余的情况。<br><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> MyStack&lt;T&gt;</span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">int</span> StackPointer=<span class="number">0</span>;</span><br><span class="line">    T[] StackArray;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">Push</span><span class="params">(T x)</span></span><br><span class="line">    </span>&#123;</span><br><span class="line">        <span class="comment">//压栈</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> T <span class="title">Pop</span><span class="params">()</span></span><br><span class="line">    </span>&#123;</span><br><span class="line">        <span class="comment">//出栈</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>　　以上是一个泛型类的声明，“T”代表类型的占位符(也可以是其他字符)，在实例化时，每一个“T”都会被编译器替换为实际类型。</p>
<h2 id="泛型类">泛型类</h2><p>　　创建和使用常规的非泛型的类有两个步骤：声明类、创建类的实例。但是泛型类不是实际的类，而是类的模板，创建时需要：<br>　　■ 在某些类型上使用占位符来声明一个泛型类。<br>　　■ 为占位符提供真实类型，这样就有了真实类型的定义，填补了所有的“空缺”。<br>　　■ 从“填空后”的类定义创建实例。<br><img src="/image/cSharp/cSharp66.png" alt=""></p>
<h3 id="声明泛型类">声明泛型类</h3><p>　　声明泛型类：<br>　　■ 在类名之后放置一组尖括号。<br>　　■ 在尖括号中用逗号分隔的占位符字符串来表示希望提供的类型。这叫做<em>类型参数(type parameter)</em>。<br>　　■ 在泛型类声明的主体中使用类型参数来表示应该被替代的类型。<br><figure class="highlight actionscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//类型参数</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">SomeClass</span> &lt;<span class="title">T1</span>,<span class="title">T2</span>&gt;</span><br><span class="line"></span>&#123;</span><br><span class="line">    <span class="comment">//通常在这些位置使用泛型类型</span></span><br><span class="line">    <span class="keyword">public</span> T1 SomeVar = <span class="keyword">new</span> T1();</span><br><span class="line">    <span class="keyword">public</span> T2 OtherVar = <span class="keyword">new</span> T2();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<h3 id="创建构造类型">创建构造类型</h3><p>　　我们不能直接从泛型类型创建类对象。<br>　　首先，我们需要告诉编译器使用哪些真实的类型来替代占位符(类型参数)，编译器获取这些真实类型并从它创建一个真实的类型对象。<br>　　★ 要从泛型类构建类类型，列出类名字并在尖括号中提供真实类型来替代类型参数，要替代类型参数的真实类型叫做<em>类型实参(type argument)</em>。<br><img src="/image/cSharp/cSharp67.png" alt=""><br>　　★ 为泛型类提供了类型实参，替换泛型类主体中的相应的类型参数，这时相当于产生了一个构造类型，从这个构造类可以创建真实类型的实例了。<br><img src="/image/cSharp/cSharp68.png" alt=""><br>　　类型参数和类型实参的区别：<br><img src="/image/cSharp/cSharp69.png" alt=""></p>
<h3 id="创建变量和实例">创建变量和实例</h3><figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//普通类对象的创建</span></span><br><span class="line">MyNonGenClass myNGC = <span class="keyword">new</span> MyNonGenClass();</span><br><span class="line"></span><br><span class="line"><span class="comment">//泛型类对象的创建吗，使用short和int类型进行实例化。</span></span><br><span class="line">SomeClass&lt;<span class="keyword">short</span>,<span class="keyword">int</span>&gt; mySc1 = <span class="keyword">new</span> SomeClass&lt;<span class="keyword">short</span>,<span class="keyword">int</span>&gt;();</span><br><span class="line"></span><br><span class="line"><span class="comment">//和第二行代码一样，区别是使用var关键字使编译器使用类型。</span></span><br><span class="line"><span class="keyword">var</span> mySc2 = <span class="keyword">new</span> SomeClass&lt;<span class="keyword">short</span>,<span class="keyword">int</span>&gt;();</span><br></pre></td></tr></table></figure>
<p>　　泛型类也可以引用和实例分开创建。<br><figure class="highlight axapta"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//泛型类声明</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">SomeClass</span> &lt;<span class="title">T1</span>,<span class="title">T2</span>&gt;</span><br><span class="line"></span>&#123;</span><br><span class="line">    <span class="keyword">public</span> T1 SomeVar;</span><br><span class="line">    <span class="keyword">public</span> T2 OtherVar;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">SomeClass&lt;<span class="keyword">short</span>,<span class="keyword">int</span>&gt; myInst; <span class="comment">//创建引用</span></span><br><span class="line">myInst = <span class="keyword">new</span> SomeClass&lt;<span class="keyword">short</span>,<span class="keyword">int</span>&gt;();  <span class="comment">//创建实例</span></span><br></pre></td></tr></table></figure></p>
<p>　　■ <code>SomeClass&lt;short,int&gt; myInst</code>这句代码在栈上为<code>myInst</code>分配了一个引用，值是null。<br>　　■ <code>myInst = new SomeClass&lt;short,int&gt;()</code>这句代码在堆上分配实例，并且把引用赋值给变量。</p>
<p>　　★ 可以从同一个泛型类型构建出不同的类类型。<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">SomeClass</span> &lt;<span class="title">T1</span>,<span class="title">T2</span>&gt;</span><br><span class="line"></span>&#123;</span><br><span class="line">    <span class="keyword">public</span> T1 SomeVar;</span><br><span class="line">    <span class="keyword">public</span> T2 OtherVar;</span><br><span class="line">&#125;</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Program</span></span><br><span class="line"></span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">Main</span><span class="params">(string[] args)</span></span><br><span class="line">    </span>&#123;</span><br><span class="line">        <span class="comment">//从同一个泛型类型构建出不同的类对象</span></span><br><span class="line">        var class1 = <span class="keyword">new</span> SomeClass&lt;<span class="keyword">short</span>,<span class="keyword">int</span>&gt;(); </span><br><span class="line">        var class2 = <span class="keyword">new</span> SomeClass&lt;<span class="keyword">int</span>,<span class="keyword">long</span>&gt;();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p><img src="/image/cSharp/cSharp70.png" alt=""></p>
<h2 id="类型参数的约束">类型参数的约束</h2><p>　　有时候我们并不能让任何类型的类型实参去匹配类型参数，也就是说需要取代“T”占位符的参数类型有时候需要有一些限制，并不是所有的代码中都需要所有的数据类型。<br>　　★ 要让泛型变的更加准确，我们需要提供额外的信息让编译器直达参数可以接受哪些类型，这些额外的信息叫做<strong>约束(constrain)</strong>，只有符合约束的实参才能用于类型参数。</p>
<h3 id="where子句">where子句</h3><p>　　约束使用where子句列出：<br>　　■ 每一个有约束的类型参数有自己的where子句。<br>　　■ 如果形参有多个约束，它们在where子中使用逗号分隔。<br><img src="/image/cSharp/cSharp71.png" alt=""><br>　　where子句要点：<br>　　■ 它们在类型参数列表的关闭尖括号之后列出。<br>　　■ 它们不使用逗号或其他符号分隔。<br>　　■ 它们可以以任何次序列出。<br><img src="/image/cSharp/cSharp72.png" alt=""></p>
<h3 id="约束类型和次序">约束类型和次序</h3><p><img src="/image/cSharp/cSharp73.png" alt=""><br>　　where子句可以以任何次序列出，但是where子句中的约束却必须有特定的顺序。<br>　　■ 最多只能由一个主约束，而且必须放在第一位。<br>　　■ 可以有任意多的<em>InterfaceName</em>约束。<br>　　■ 如果存在构造函数约束(<em>new()</em>)，则必须放在最后。<br><img src="/image/cSharp/cSharp74.png" alt=""><br><strong>示例</strong>：<br><figure class="highlight ruby"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">SortedList</span><span class="inheritance">&lt;<span class="parent">S</span></span>&gt;</span></span><br><span class="line">        where <span class="constant">S</span><span class="symbol">:IComparable&lt;S&gt;</span></span><br><span class="line">    &#123;</span><br><span class="line">        ...</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Linkedist</span><span class="inheritance">&lt;<span class="parent">M</span></span>,<span class="title">N</span>&gt;</span></span><br><span class="line">        where <span class="constant">M</span><span class="symbol">:IComparable&lt;S&gt;</span></span><br><span class="line">        where <span class="constant">N</span><span class="symbol">:ICloneable</span></span><br><span class="line">    &#123;</span><br><span class="line">        ...</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyDictionary</span><span class="inheritance">&lt;<span class="parent">KeyType</span></span>,<span class="title">ValueType</span>&gt;</span></span><br><span class="line">        where <span class="constant">KeyType</span><span class="symbol">:IEnumerable</span>,new()</span><br><span class="line">    &#123;</span><br><span class="line">        ...</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure></p>
<h2 id="泛型结构">泛型结构</h2><p>　　与泛型类相似，泛型结构可以有类型参数和约束。<strong>泛型结构的规则和条件与泛型类是一样的</strong>。<br><figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title">Program</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">Main</span>(<span class="params"><span class="keyword">string</span>[] args</span>)</span><br><span class="line">    </span>&#123;</span><br><span class="line">        <span class="keyword">var</span> intData = <span class="keyword">new</span> ShowData&lt;<span class="keyword">int</span>&gt;(<span class="number">10</span>);</span><br><span class="line">        <span class="keyword">var</span> stringData = <span class="keyword">new</span> ShowData&lt;<span class="keyword">string</span>&gt;(<span class="string">"struct"</span>);</span><br><span class="line">        Console.WriteLine(intData.Data);</span><br><span class="line">        Console.WriteLine(stringData.Data);</span><br><span class="line">        Console.ReadKey();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">struct</span> ShowData&lt;T&gt;</span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">public</span> T Data &#123; <span class="keyword">get</span>; <span class="keyword">set</span>; &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ShowData</span> (<span class="params">T <span class="keyword">value</span></span>)</span><br><span class="line">    </span>&#123;</span><br><span class="line">        Data = <span class="keyword">value</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>运行结果：<br><img src="/image/cSharp/cSharp78.png" alt=""></p>
<h2 id="泛型接口">泛型接口</h2><p>　　泛型接口允许我们编写<em>参数</em>和<em>成员返回类型</em>是<em>泛型类型参数</em>的接口。</p>
<h3 id="声明泛型接口示例">声明泛型接口示例</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//参数和成员的返回类型都是泛型T</span></span><br><span class="line">interface IMyIfc&lt;T&gt;  </span><br><span class="line">&#123;</span><br><span class="line">    <span class="function">T <span class="title">ReturenIt</span><span class="params">(T inValue)</span></span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//泛型类实现泛型接口，非泛型类也可实现泛型接口</span></span><br><span class="line"><span class="keyword">class</span> Simple&lt;S&gt; : IMyIfc&lt;S&gt;  </span><br><span class="line">&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> S <span class="title">ReturnIt</span><span class="params">(S inValue)</span></span><br><span class="line">    </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> inValue;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> Program</span><br><span class="line">&#123;</span><br><span class="line">    <span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">Main</span><span class="params">(<span class="built_in">string</span>[] args)</span></span><br><span class="line">    </span>&#123;</span><br><span class="line">        <span class="comment">//两种不同的参数类型</span></span><br><span class="line">        var trivInt = <span class="keyword">new</span> Simple&lt;<span class="keyword">int</span>&gt;();</span><br><span class="line">        var trivString = <span class="keyword">new</span> Simple&lt;<span class="built_in">string</span>&gt;();</span><br><span class="line">        </span><br><span class="line">        Console.WriteLine(trivInt.ReturnIt(<span class="number">5</span>));</span><br><span class="line">        Console.WriteLine(trivString.ReturnIt(<span class="string">"泛型接口"</span>));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>###　使用泛型接口示例<br>　　■ 与其他的泛型相似，同一个接口，实现了不同<em>类型参数</em>就是不同的接口(比如<code>IIfc&lt;int&gt;</code>和<code>IIfc&lt;string&gt;</code>虽然是同一个接口，但是由于类型参数不同，就是不同的接口)。<br>　　■ 可以在非泛型类中实现泛型接口。<br><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">interface IMyIfc&lt;T&gt;</span><br><span class="line">&#123;</span><br><span class="line">    <span class="function">T <span class="title">ReturnIt</span><span class="params">(T inValue)</span></span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//源于同一个的泛型接口的两个不同接口</span></span><br><span class="line"><span class="keyword">class</span> Simple : IMyIfc&lt;<span class="keyword">int</span>&gt;,IMyIfc&lt;<span class="built_in">string</span>&gt;</span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">//实现int类型接口</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">ReturnIt</span><span class="params">(<span class="keyword">int</span> inValue)</span>  </span><br><span class="line">    </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> inValue;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//实现string类型接口</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="built_in">string</span> <span class="title">ReturnIt</span><span class="params">(<span class="built_in">string</span> inValue)</span></span><br><span class="line">    </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> inValue;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">class</span> Program</span><br><span class="line">&#123;</span><br><span class="line">    <span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">Main</span><span class="params">(<span class="built_in">string</span>[] args)</span></span><br><span class="line">    </span>&#123;</span><br><span class="line">        <span class="comment">//两种不同的参数类型</span></span><br><span class="line">        var trivInt = <span class="keyword">new</span> Simple&lt;<span class="keyword">int</span>&gt;();</span><br><span class="line">        var trivString = <span class="keyword">new</span> Simple&lt;<span class="built_in">string</span>&gt;();</span><br><span class="line">        </span><br><span class="line">        Console.WriteLine(trivInt.ReturnIt(<span class="number">5</span>));</span><br><span class="line">        Console.WriteLine(trivString.ReturnIt(<span class="string">"泛型接口"</span>));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<h3 id="泛型接口的实现必须唯一">泛型接口的实现必须唯一</h3><p>　　在实现泛型接口时，必须确定的是不能让一个类去实现两个相同的接口，这是必须避免发生的，以下代码展示了这种情况的例子：<br><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">interface IMyIfc&lt;T&gt;</span><br><span class="line">&#123;</span><br><span class="line">    <span class="function">T <span class="title">ReturnIt</span><span class="params">(T inValue)</span></span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//错误的代码，因为如果泛型“S”也是int类型，那么就相当于Simple类实现了两个相同的IMyIfc接口。</span></span><br><span class="line"><span class="keyword">class</span> Simple&lt;S&gt; : IMyIfc&lt;<span class="keyword">int</span>&gt;,IMyIfc&lt;S&gt;</span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">//实现第一个接口</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">ReturnIt</span><span class="params">(<span class="keyword">int</span> inValue)</span></span><br><span class="line">    </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> inValue;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//实现第二个接口，如果它是int类型，就会出现错误异常</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> S <span class="title">ReturnIt</span><span class="params">(S inValue)</span></span><br><span class="line">    </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> inValue;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>　　<strong>泛型接口的名字不会和非泛型冲突，比如</strong><code>IMyIfc&lt;T&gt;</code><strong>和</strong><code>IMyIfc</code><strong>是不会有命名冲突的。</strong></p>
<h2 id="泛型委托">泛型委托</h2><p><img src="/image/cSharp/cSharp79.png" alt=""><br>　　■ 要声明泛型委托，在委托名称和委托参数列表之间的尖括号中放类型参数列表。<br>　　■ 这里有两个参数列表，委托形参列表和类型参数列表<br>　　■ 类型参数的范围包括：<br>　　　　□ 返回值<br>　　　　□ 形参列表<br>　　　　□ 约束子句<br><figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">delegate</span> <span class="keyword">void</span> MyDeledate&lt;T&gt;(T <span class="keyword">value</span>);   <span class="comment">//泛型委托</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title">Simple</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="function"><span class="keyword">static</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title">PrintString</span>(<span class="params"><span class="keyword">string</span> s</span>)  <span class="comment">//方法匹配委托</span></span><br><span class="line">    </span>&#123;</span><br><span class="line">        Console.WriteLine(s);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">static</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title">PrintUpperString</span>(<span class="params"><span class="keyword">string</span> s</span>)  <span class="comment">//方法匹配委托</span></span><br><span class="line">    </span>&#123;</span><br><span class="line">        Console.WriteLine(s.ToUpper());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title">Program</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">Main</span>(<span class="params"><span class="keyword">string</span>[] args</span>)</span><br><span class="line">    </span>&#123;</span><br><span class="line">        <span class="keyword">var</span> myDel = <span class="keyword">new</span> MyDeledate&lt;<span class="keyword">string</span>&gt;(Simple.PrintString);  <span class="comment">//创建委托实例</span></span><br><span class="line">        myDel += Simple.PrintUpperString;   <span class="comment">//添加方法</span></span><br><span class="line">        myDel(<span class="string">"generic_delegate"</span>);            <span class="comment">//调用委托</span></span><br><span class="line">        Console.ReadKey();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>运行结果：<img src="/image/cSharp/cSharp80.png" alt=""></p>
<h2 id="泛型方法">泛型方法</h2><p>　　与其他泛型不一样的是，方法是成员，不是类型。<br>　　<strong>泛型方法可以在泛型和非泛型类以及结构和接口中声明。</strong><br><img src="/image/cSharp/cSharp81.png" alt=""></p>
<h3 id="声明泛型方法">声明泛型方法</h3><p>　　■ 泛型方法和泛型委托一样，有两个参数列表：方法参数列表、类型参数列表。<br><img src="/image/cSharp/cSharp82.png" alt=""></p>
<h3 id="调用泛型方法">调用泛型方法</h3><p>　　要调用泛型方法，应该在方法调用时提供类型实参：<br><figure class="highlight aspectj"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">MyMethod&lt;<span class="keyword">short</span>,<span class="keyword">int</span>&gt;();</span><br><span class="line">MyMethod&lt;<span class="keyword">int</span>,<span class="keyword">long</span>&gt;();</span><br></pre></td></tr></table></figure></p>
<p>有两个实例的泛型方法：<br><img src="/image/cSharp/cSharp83.png" alt=""></p>
<h3 id="推断类型">推断类型</h3><p>　　如果我们为泛型方法传入了参数，编译器可以根据传入的参数判断类型参数的类型，因此可以省略类型参数，形成简写形式：<br><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//类型参数列表和方法参数列表都是“T”类型</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> MyMethod &lt;T&gt; (T myVal)</span><br><span class="line">&#123;</span><br><span class="line">    ...</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> MyInt=<span class="number">5</span>;</span><br><span class="line">MyMethod &lt;<span class="keyword">int</span>&gt; (MyInt);  <span class="comment">//两个类型都是int类型的</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//可以简写成</span></span><br><span class="line">MyMethod (MyInt);</span><br></pre></td></tr></table></figure></p>
<h3 id="泛型方法的示例">泛型方法的示例</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> Simple          <span class="comment">//非泛型类</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">public</span> <span class="keyword">void</span> ReverseAndPrint&lt;T&gt;(T[] arr)  <span class="comment">//泛型方法</span></span><br><span class="line">    &#123;</span><br><span class="line">        Array.Reverse(arr);</span><br><span class="line">        foreach (T item in arr)</span><br><span class="line">        &#123;</span><br><span class="line">            Console.Write(<span class="string">"&#123;0&#125;，"</span>,item.ToString());</span><br><span class="line">        &#125;</span><br><span class="line">        Console.WriteLine(<span class="string">""</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> Program</span><br><span class="line">&#123;</span><br><span class="line">    <span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">Main</span><span class="params">(<span class="built_in">string</span>[] args)</span></span><br><span class="line">    </span>&#123;</span><br><span class="line">        var intArray = <span class="keyword">new</span> <span class="keyword">int</span>[] &#123; <span class="number">3</span>, <span class="number">5</span>, <span class="number">7</span>, <span class="number">9</span>, <span class="number">11</span> &#125;;</span><br><span class="line">        var stringArray = <span class="keyword">new</span> <span class="built_in">string</span>[] &#123; <span class="string">"壹"</span>, <span class="string">"贰"</span>, <span class="string">"叁"</span> &#125;;</span><br><span class="line">        var doubleArray = <span class="keyword">new</span> <span class="keyword">double</span>[] &#123; <span class="number">1.11</span>, <span class="number">2.33</span>, <span class="number">4.44</span> &#125;;</span><br><span class="line"></span><br><span class="line">        Simple.ReverseAndPrint&lt;<span class="keyword">int</span>&gt;(intArray);   <span class="comment">//调用方法</span></span><br><span class="line">        Simple.ReverseAndPrint(intArray);        <span class="comment">//简写</span></span><br><span class="line">        </span><br><span class="line">        Simple.ReverseAndPrint&lt;<span class="built_in">string</span>&gt;(stringArray);   <span class="comment">//调用方法</span></span><br><span class="line">        Simple.ReverseAndPrint(stringArray);        <span class="comment">//简写</span></span><br><span class="line"></span><br><span class="line">        Simple.ReverseAndPrint&lt;<span class="keyword">double</span>&gt;(doubleArray);   <span class="comment">//调用方法</span></span><br><span class="line">        Simple.ReverseAndPrint(doubleArray);        <span class="comment">//简写</span></span><br><span class="line"></span><br><span class="line">        Console.ReadKey();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>运行结果：<br><img src="/image/cSharp/cSharp84.png" alt=""></p>

      
    </div>

    
      

    
    <br/><br/>
<!--baidu share-->

<div class="bdsharebuttonbox"><a class="bds_more" href="#" data-cmd="more">分享到：</a><a title="分享到新浪微博" class="bds_tsina" href="#" data-cmd="tsina">新浪微博</a><a title="分享到微信" class="bds_weixin" href="#" data-cmd="weixin">微信</a><a title="分享到QQ空间" class="bds_qzone" href="#" data-cmd="qzone">QQ空间</a><a title="分享到QQ好友" class="bds_sqq" href="#" data-cmd="sqq">QQ好友</a></div>
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{"bdSize":16}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
  
<!--baidu share-->
    <footer class="article-footer">
      <a data-url="/2015/05/22/c#-generic/" data-id="ciqvzmhn60011csvlty3glq04" class="article-share-link">
        <i class="fa fa-share"></i> Share
      </a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/c-学习笔记/">c#学习笔记</a></li></ul>


    </footer>
  </div>
  
    
<ul id="article-nav" class="nav nav-pills nav-justified">
  
  <li role="presentation">
    <a href="/2015/05/21/c#-Event/" id="article-nav-older" class="article-nav-link-wrap">
      <i class="fa fa-chevron-left pull-left"></i>
      <span class="article-nav-link-title">事件(Event)</span>
    </a>
  </li>
  
  
  <li role="presentation">
    <a href="/2015/05/24/c#-struct/" id="article-nav-newer" class="article-nav-link-wrap">
      <span class="article-nav-link-title">结构(struct)</span>
      <i class="fa fa-chevron-right pull-right"></i>
    </a>
  </li>
  
</ul>


  
</article>


<section id="comments">
  <div id="disqus_thread">
    <!-- 多说评论框 start -->
	<div class="ds-thread" data-thread-key="2015/05/22/c#-generic/" data-title="泛型(generic)" data-url="/2015/05/22/c#-generic/"></div>
<!-- 多说评论框 end -->
<!-- 多说公共JS代码 start (一个网页只需插入一次) -->
<script type="text/javascript">
var duoshuoQuery = {short_name:"hais2"};
	(function() {
		var ds = document.createElement('script');
		ds.type = 'text/javascript';ds.async = true;
		ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
		ds.charset = 'UTF-8';
		(document.getElementsByTagName('head')[0] 
		 || document.getElementsByTagName('body')[0]).appendChild(ds);
	})();
	</script>
<!-- 多说公共JS代码 end -->
  </div>
</section>


        </div>
        <div class="col-sm-3 col-sm-offset-1 blog-sidebar">
          
  <div class="sidebar-module sidebar-module-inset">
<a style="text-decoration:none" title="有本事点我一下试试.." href='javascript:(function() {
	function c() {
		var e = document.createElement("link");
		e.setAttribute("type", "text/css");
		e.setAttribute("rel", "stylesheet");
		e.setAttribute("href", f);
		e.setAttribute("class", l);
		document.body.appendChild(e)
	}
 
	function h() {
		var e = document.getElementsByClassName(l);
		for (var t = 0; t < e.length; t++) {
			document.body.removeChild(e[t])
		}
	}
 
	function p() {
		var e = document.createElement("div");
		e.setAttribute("class", a);
		document.body.appendChild(e);
		setTimeout(function() {
			document.body.removeChild(e)
		}, 100)
	}
 
	function d(e) {
		return {
			height : e.offsetHeight,
			width : e.offsetWidth
		}
	}
 
	function v(i) {
		var s = d(i);
		return s.height > e && s.height < n && s.width > t && s.width < r
	}
 
	function m(e) {
		var t = e;
		var n = 0;
		while (!!t) {
			n += t.offsetTop;
			t = t.offsetParent
		}
		return n
	}
 
	function g() {
		var e = document.documentElement;
		if (!!window.innerWidth) {
			return window.innerHeight
		} else if (e && !isNaN(e.clientHeight)) {
			return e.clientHeight
		}
		return 0
	}
 
	function y() {
		if (window.pageYOffset) {
			return window.pageYOffset
		}
		return Math.max(document.documentElement.scrollTop, document.body.scrollTop)
	}
 
	function E(e) {
		var t = m(e);
		return t >= w && t <= b + w
	}
 
	function S() {
		var e = document.createElement("audio");
		e.setAttribute("class", l);
		e.src = i;
		e.loop = false;
		e.addEventListener("canplay", function() {
			setTimeout(function() {
				x(k)
			}, 500);
			setTimeout(function() {
				N();
				p();
				for (var e = 0; e < O.length; e++) {
					T(O[e])
				}
			}, 15500)
		}, true);
		e.addEventListener("ended", function() {
			N();
			h()
		}, true);
		e.innerHTML = " <p>If you are reading this, it is because your browser does not support the audio element. We recommend that you get a new browser.</p> <p>";
		document.body.appendChild(e);
		e.play()
	}
 
	function x(e) {
		e.className += " " + s + " " + o
	}
 
	function T(e) {
		e.className += " " + s + " " + u[Math.floor(Math.random() * u.length)]
	}
 
	function N() {
		var e = document.getElementsByClassName(s);
		var t = new RegExp("\\b" + s + "\\b");
		for (var n = 0; n < e.length; ) {
			e[n].className = e[n].className.replace(t, "")
		}
	}
 
	var e = 30;
	var t = 30;
	var n = 350;
	var r = 350;
	var i = "//s3.amazonaws.com/moovweb-marketing/playground/harlem-shake.mp3";
	var s = "mw-harlem_shake_me";
	var o = "im_first";
	var u = ["im_drunk", "im_baked", "im_trippin", "im_blown"];
	var a = "mw-strobe_light";
	var f = "//s3.amazonaws.com/moovweb-marketing/playground/harlem-shake-style.css";
	var l = "mw_added_css";
	var b = g();
	var w = y();
	var C = document.getElementsByTagName("*");
	var k = null;
	for (var L = 0; L < C.length; L++) {
		var A = C[L];
		if (v(A)) {
			if (E(A)) {
				k = A;
				break
			}
		}
	}
	if (A === null) {
		console.warn("Could not find a node of the right size. Please try a different page.");
		return
	}
	c();
	S();
	var O = [];
	for (var L = 0; L < C.length; L++) {
		var A = C[L];
		if (v(A)) {
			O.push(A)
		}
	}
})()'>
    <h4>Hi</h4>
</a>

  
  <h5>我是海建东,欢迎访问我的博客.</h5>

</div>


  
  <div class="sidebar-module">
    <h4>分类</h4>
    <ul class="sidebar-module-list"><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/ASP-NET/">ASP.NET</a><span class="sidebar-module-list-count">4</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/ASP-NET-Web-API/">ASP.NET Web API</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/Asp-Net-MVC/">Asp.Net MVC</a><span class="sidebar-module-list-count">3</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/Git/">Git</a><span class="sidebar-module-list-count">3</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/Hexo/">Hexo</a><span class="sidebar-module-list-count">10</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/SQL/">SQL</a><span class="sidebar-module-list-count">8</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/UWP/">UWP</a><span class="sidebar-module-list-count">2</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/Umbraco/">Umbraco</a><span class="sidebar-module-list-count">11</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/c/">c#</a><span class="sidebar-module-list-count">18</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/前端开发/">前端开发</a><span class="sidebar-module-list-count">3</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/文集/">文集</a><span class="sidebar-module-list-count">12</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/categories/设计模式/">设计模式</a><span class="sidebar-module-list-count">6</span></li></ul>
  </div>



  
  <div class="sidebar-module">
    <h4>标签</h4>
    <ul class="sidebar-module-list"><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/ASP-NET/">ASP.NET</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/ASP-NET-Core/">ASP.NET Core</a><span class="sidebar-module-list-count">2</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/ASP-NET-Web-API笔记/">ASP.NET Web API笔记</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/AngularJS/">AngularJS</a><span class="sidebar-module-list-count">2</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/Asp-Net-MVC/">Asp.Net MVC</a><span class="sidebar-module-list-count">3</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/EntityFramework/">EntityFramework</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/Git学习/">Git学习</a><span class="sidebar-module-list-count">3</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/Hexo博客搭建/">Hexo博客搭建</a><span class="sidebar-module-list-count">10</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/SQL-Server/">SQL Server</a><span class="sidebar-module-list-count">8</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/UWP学习笔记/">UWP学习笔记</a><span class="sidebar-module-list-count">2</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/Umbraco入门/">Umbraco入门</a><span class="sidebar-module-list-count">11</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/WebForm/">WebForm</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/c-基础知识/">c#基础知识</a><span class="sidebar-module-list-count">6</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/c-学习笔记/">c#学习笔记</a><span class="sidebar-module-list-count">12</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/jQuery/">jQuery</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/影评：其实就是观后感/">影评：其实就是观后感</a><span class="sidebar-module-list-count">4</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/设计模式学习笔记/">设计模式学习笔记</a><span class="sidebar-module-list-count">6</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/转载/">转载</a><span class="sidebar-module-list-count">7</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/tags/随笔/">随笔</a><span class="sidebar-module-list-count">8</span></li></ul>
  </div>



  
  <div class="sidebar-module">
    <h4>归档</h4>
    <ul class="sidebar-module-list"><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2016/07/">七月 2016</a><span class="sidebar-module-list-count">4</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2016/05/">五月 2016</a><span class="sidebar-module-list-count">3</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2016/04/">四月 2016</a><span class="sidebar-module-list-count">2</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2016/03/">三月 2016</a><span class="sidebar-module-list-count">14</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2016/02/">二月 2016</a><span class="sidebar-module-list-count">6</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2016/01/">一月 2016</a><span class="sidebar-module-list-count">23</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2015/10/">十月 2015</a><span class="sidebar-module-list-count">2</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2015/09/">九月 2015</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2015/08/">八月 2015</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2015/07/">七月 2015</a><span class="sidebar-module-list-count">2</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2015/06/">六月 2015</a><span class="sidebar-module-list-count">4</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2015/05/">五月 2015</a><span class="sidebar-module-list-count">7</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2015/04/">四月 2015</a><span class="sidebar-module-list-count">6</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2015/03/">三月 2015</a><span class="sidebar-module-list-count">2</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2015/02/">二月 2015</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2015/01/">一月 2015</a><span class="sidebar-module-list-count">1</span></li><li class="sidebar-module-list-item"><a class="sidebar-module-list-link" href="/archives/2014/11/">十一月 2014</a><span class="sidebar-module-list-count">2</span></li></ul>
  </div>



  <!---->
  <div class="sidebar-module">
    <h4>最近访客</h4>
    <!--<ul class="sidebar-module-list">
      
        <li>
          <a href="/2016/07/19/Journey-Under-the-Midnight-Sun/">行走在白昼的夜里</a>
        </li>
      
        <li>
          <a href="/2016/07/18/Hexo-misspelled-tag/">Hexo标签分类写错的处理</a>
        </li>
      
        <li>
          <a href="/2016/07/17/Value-types-and-reference-types/">值类型和引用类型</a>
        </li>
      
        <li>
          <a href="/2016/07/17/Fiddler-caught-analysis-API/">使用Fiddler抓包分析API</a>
        </li>
      
        <li>
          <a href="/2016/05/14/Hexo-Getting-Started-1/">8、使用SSH方式部署博客</a>
        </li>
      
    </ul>
    
    <div class="ds-recent-visitors" data-num-items="12" data-avatar-size="28" id="ds-recent-visitors"></div>
-->
<!-- 多说最新评论 start -->
	<div class="ds-recent-comments" data-num-items="5" data-show-avatars="1" data-show-time="1" data-show-title="1" data-show-admin="0" data-excerpt-length="20"></div>
<!-- 多说最新评论 end -->
<!-- 多说公共JS代码 start (一个网页只需插入一次) -->
<script type="text/javascript">
var duoshuoQuery = {short_name:"hais2"};
	(function() {
		var ds = document.createElement('script');
		ds.type = 'text/javascript';ds.async = true;
		ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
		ds.charset = 'UTF-8';
		(document.getElementsByTagName('head')[0] 
		 || document.getElementsByTagName('body')[0]).appendChild(ds);
	})();
	</script>
<!-- 多说公共JS代码 end -->
<br><br>
<!---->

  
  <div class="sidebar-module">
    <h4>标签云</h4>
    <p class="tagcloud">
      <a href="/tags/ASP-NET/" style="font-size: 10px;">ASP.NET</a> <a href="/tags/ASP-NET-Core/" style="font-size: 11.11px;">ASP.NET Core</a> <a href="/tags/ASP-NET-Web-API笔记/" style="font-size: 10px;">ASP.NET Web API笔记</a> <a href="/tags/AngularJS/" style="font-size: 11.11px;">AngularJS</a> <a href="/tags/Asp-Net-MVC/" style="font-size: 12.22px;">Asp.Net MVC</a> <a href="/tags/EntityFramework/" style="font-size: 10px;">EntityFramework</a> <a href="/tags/Git学习/" style="font-size: 12.22px;">Git学习</a> <a href="/tags/Hexo博客搭建/" style="font-size: 17.78px;">Hexo博客搭建</a> <a href="/tags/SQL-Server/" style="font-size: 16.67px;">SQL Server</a> <a href="/tags/UWP学习笔记/" style="font-size: 11.11px;">UWP学习笔记</a> <a href="/tags/Umbraco入门/" style="font-size: 18.89px;">Umbraco入门</a> <a href="/tags/WebForm/" style="font-size: 10px;">WebForm</a> <a href="/tags/c-基础知识/" style="font-size: 14.44px;">c#基础知识</a> <a href="/tags/c-学习笔记/" style="font-size: 20px;">c#学习笔记</a> <a href="/tags/jQuery/" style="font-size: 10px;">jQuery</a> <a href="/tags/影评：其实就是观后感/" style="font-size: 13.33px;">影评：其实就是观后感</a> <a href="/tags/设计模式学习笔记/" style="font-size: 14.44px;">设计模式学习笔记</a> <a href="/tags/转载/" style="font-size: 15.56px;">转载</a> <a href="/tags/随笔/" style="font-size: 16.67px;">随笔</a>
    </p>
  </div>


  
  <div class="sidebar-module">
     <iframe width="100%" height="550" class="share_self"  frameborder="0" scrolling="no" src="http://widget.weibo.com/weiboshow/index.php?language=&width=0&height=550&fansRow=2&ptype=1&speed=0&skin=5&isTitle=1&noborder=0&isWeibo=1&isFans=1&uid=3311041262&verifier=85e63399&dpc=1"></iframe>
  </div>


  
  <div class="sidebar-module">
    <h4>友情链接</h4>
    <a href="http://www.cnblogs.com/artech/" target="_blank">Artech</a><br/>
    <a href="http://www.deepthink.pub" target="_blank">DeepThink</a><br/>
    <a href="http://edi.wang/" target="_blank">Edi.wang</a><br/>
    <a href="http://www.lanhusoft.com/Article/List" target="_blank">LanHuSoft</a><br/>
    <a href="http://www.ruanyifeng.com/blog/" target="_blank">阮一峰的网络日志</a><br/>
    <a href="http://www.cnblogs.com/shanyou/" target="_blank">张善友</a><br/>
  </div>




        </div>
    </div>
  </div>
  <footer class="blog-footer">
  <div class="container">
    <div id="footer-info" class="inner">
      &copy; 2016 Is2<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a> and <a href="https://github.com/haijiandong/haijiandong.github.io" target="_blank">GitHub</a><br/>
      Total <span id="busuanzi_value_site_pv"></span> views.  Total <span id="busuanzi_value_site_uv"></span> guests.  Total <span id="busuanzi_value_page_pv"></span> Hits.
    </div>
  </div>
</footer>

  

<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>


<script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>


  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css" type="text/css">
  <script src="/fancybox/jquery.fancybox.pack.js" type="text/javascript"></script>


<script src="/js/script.js" type="text/javascript"></script>

</body>
</html>